package com.colin.config;


import com.colin.core.PathCollect;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
@EnableConfigurationProperties(PathCollectProperties.class)
// 当前进程中存在RabbitTemplate字节码对象
@ConditionalOnClass(RabbitTemplate.class)
// 保证IOC容器中起码存在一个类型为 RabbitTemplate 的Spring Bean
@ConditionalOnSingleCandidate(RabbitTemplate.class)
// 当前的自动配置执行 必须在 Rabbit自动配置执行之后
@AutoConfigureAfter({RabbitAutoConfiguration.class})
public class PathCollectAutoConfig {

    /**
     * Spring 单例bean的生命周期
     *
     * 在IOC容器初始化时 单例bean就要开始初始化 当IOC可以被使用时 单例bean全都就绪了
     * SSM
     * Spring MVC 在 web.xml中配置了一个 DispatcherServlet 扫描一个spring-config.xml的路径 用于构建一个IOC
     * DispatcherServlet 还有一个loadonstartup标签配置 声明在Tomcat启动时立即创建
     *
     * 在SSM项目 IOC是什么时候开始构建并且完成的呢？   是在Tomcat启动时开始构建 Tomcat启动完成可以被访问时 IOC也构建完成
     *
     *
     *
     * @param properties
     */
    @Bean
    @Scope("singleton")
    public PathCollect pathCollect(PathCollectProperties properties, RabbitTemplate rabbitTemplate) {
        return new PathCollect(properties, rabbitTemplate);
    }


    /**
     * 上一个视频我们做到的事情是：
     * 让用户自己定义一个队列 然后把我们依赖采集的需要登录验证的路径 发送到队列
     *
     * 想办法在自动配置boot starter中 自动帮开发人员创建一个队列 并自动发送采集信息到指定队列
     * 1. 如何通过代码创建指定队列
     * 在Spring Boot中我们可以直接向IOC容器中注入一个 Queue类型的对象 构建这个对象的构造方法可以传入队列名称作为参数
     *
     * 通过这种方式创建的队列
     * 如果RabbitMQ服务中已存在这个队列 不会再创建 也不是删除再创建 而是直接使用
     * 当使用我们bootstarter的用户在开发或者测试阶段 可能频繁重启项目 那么就会导致 很多接口路径会被重复的添加到队列中
     *
     * 我们可以这样去解决： 网关监听指定队列的时候 准备一个Set集合（去重） 对于网关通过消费获取到队列中所有的接口路径都去放入这个set集合
     * 哪儿怕后续有重复的需要登录验证的路径 放入set集合也会自动去重
     *
     * 2. 在教大家RabbitMQ的时候 发送消息是使用了一个代言人对象： RabbitTemplate
     * 可以通过条件化判断 + 自动装配在当前类中获取到 RabbitTemplate
     *
     * 3. 我们拿到RabbitTemplate不要在这个自动配置类中做这个事儿 我们尽可能还是放在 PathCollect类中执行发送消息的代码
     */
    @Bean
    public Queue queue(PathCollectProperties properties) {
        return new Queue(properties.getQueueName());
    }
}
